package com.atjava.nebula.eims.comdoc.action;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.atjava.nebula.core.dao.ibatis.Condition;
import com.atjava.nebula.core.exception.baseExp.BusinessException;
import com.atjava.nebula.core.exception.baseExp.SystemException;
import com.atjava.nebula.core.service.GenericService;
import com.atjava.nebula.core.tablexml.view.Column;
import com.atjava.nebula.core.tablexml.view.Grid;
import com.atjava.nebula.core.tablexml.view.Query;
import com.atjava.nebula.core.tablexml.view.ViewConfig;
import com.atjava.nebula.core.util.context.SpringContextHolder;
import com.atjava.nebula.core.util.entity.EntitySupport;
import com.atjava.nebula.core.util.excel.ExcelUtil;
import com.atjava.nebula.eims.comdoc.model.MoDocDef;
import com.atjava.nebula.eims.comdoc.model.MoDocList;
import com.atjava.nebula.eims.comdoc.model.MoDocValue;
import com.atjava.nebula.eims.comdoc.service.CommonDocService;
import com.atjava.nebula.web.action.BaseAction;
import com.atjava.nebula.web.constant.ProjectConst;
import com.atjava.nebula.web.view.XmlViewConfiguration;
import com.atjava.nebula.web.view.XmlViewManager;

@Controller
@RequestMapping("/eims/comdoc")
public class CommonDocAction extends BaseAction {
	
	public static String CATALOG = "eims";
	public static String ENTITY_DEF = "docdef";
	public static String ENTITY_VAL = "docvalue";

	@SuppressWarnings("unchecked")
	@RequestMapping(value="/docdef/add",method = RequestMethod.POST)
	@ResponseBody
	public boolean uploadDoc(
			HttpServletRequest request,
			@RequestParam int importType,
			@RequestParam CommonsMultipartFile docFile) 
			throws SystemException, IOException, BusinessException{
		
		String fileName = docFile.getOriginalFilename();
		
		if(!ExcelUtil.isExcelFile(fileName)){
			throw new SystemException("file ["+fileName+"] is not a Excel file !");
		}
		
		String [][] data = ExcelUtil.readExcelData(docFile.getInputStream(), fileName, 0);
		
		CommonDocService comdocService = (CommonDocService)SpringContextHolder.getBean("eims.docdef");
		
		MoDocDef docDef;
		
		//select document
		if(0 == importType){
			
			String docId = request.getParameter("docId");
			GenericService<MoDocDef,Short> docdefService = (GenericService<MoDocDef, Short>)
					getService(ProjectConst.CATALOG_EIMS, ProjectConst.MODULE_DOCDEF);
			docDef = docdefService.getById(Short.parseShort(docId));
		
		//new document
		}else{
			docDef = new MoDocDef();
			String name = request.getParameter("name");
			String queryIndex = request.getParameter("queryIndex");
			String userIdIndex = request.getParameter("userIdIndex");
			docDef.setName(name);
			docDef.setQueryIndex(queryIndex);
			if(StringUtils.isNotBlank(userIdIndex)){
				docDef.setUserIdIndex(Short.parseShort(userIdIndex));
			}
			docDef.setCreateTime(new Date());
		}
		
		comdocService.importDocument(docDef, data);
		
		return true;
	}
	
	@SuppressWarnings("unchecked")
	@RequestMapping("/docdef/delete")
	@ResponseBody
	public boolean doDelete(HttpServletRequest request, 
			HttpServletResponse response,
			@RequestParam(REQ_PARAM_QUERYPK) String [] pkid,
			ModelMap modelMap) throws SystemException, BusinessException {
		
		GenericService<MoDocDef,Short> docdefService = (GenericService<MoDocDef, Short>)
				getService(ProjectConst.CATALOG_EIMS, ProjectConst.MODULE_DOCDEF);
		
		GenericService<MoDocValue,Long> docvalService = (GenericService<MoDocValue, Long>)
				getService(ProjectConst.CATALOG_EIMS, ProjectConst.MODULE_DOCVALUE);
		
		MoDocValue docValue = new MoDocValue();
		for (int i = 0; i < pkid.length; i++) {
			
			MoDocDef docdef = (MoDocDef) EntitySupport.getPkToEntity(MoDocDef.class,pkid[i]);
			Short docId = docdef.getPkid();
			docValue.setDocId(docId);
			docvalService.remove(docValue);
			docdefService.removeById(docId);
		}
		
		return true;
		
	}
	
	@RequestMapping("/docvalue/data")
	@ResponseBody
	public MoDocList listGridData(HttpServletRequest request, 
			@RequestParam(REQ_PARAM_GRIDID) String gridId,
			@RequestParam Short docid,
			String userId) throws SystemException, BusinessException {
		
		GenericService<MoDocValue,Short> valService = getService(MoDocValue.class,Short.class);
		GenericService<MoDocDef,Short> defService = getService(MoDocDef.class,Short.class);
		ViewConfig config = XmlViewManager.getXmlViewConfig
				(ProjectConst.CATALOG_EIMS, ProjectConst.MODULE_DOCVALUE);
		
		MoDocDef def = defService.getById(docid);
		
		//search condition
		Condition cond = new Condition();
		String queryId = request.getParameter(REQ_PARAM_QUERYID);
		if(StringUtils.isNotBlank(queryId)){
			Query query = XmlViewManager.getQuery(config, queryId);
			cond = getConditionFromRequest(request, query);
		}
		cond.addCriterion("DOC_ID", "=", docid);
		if(StringUtils.isNotBlank(userId)){
			cond.addCriterion("USER_ID", "=", userId);
		}
		List<MoDocValue> list = valService.list(cond);
		
		MoDocList docList = new MoDocList();
		docList.setDocDef(def);
		docList.setDocData(list);
		
		return docList;
	}
	
	@RequestMapping("/docvalue/config")
	@ResponseBody
	public Grid gridViewConfig(HttpServletRequest request, 
			@RequestParam(REQ_PARAM_GRIDID) String gridId,
			@RequestParam Short docid,
			ViewConfig config) throws SystemException, BusinessException {
		
		//xml view config
		if(config.getSource() == null){
			config = XmlViewManager.getXmlViewConfig
					(ProjectConst.CATALOG_EIMS, ProjectConst.MODULE_DOCVALUE);
		}
		Grid grid = XmlViewManager.getGrid(config, gridId);
		
		grid.setColumns(null);
		
		GenericService<MoDocDef,Short> defService = getService(MoDocDef.class,Short.class);
		
		MoDocDef def = defService.getById(docid);
		if(def == null)
			throw new BusinessException("Document [id="+docid+"] can not be found!");
		
		String [] header = def.getHeader().split(ProjectConst.SPLIT_KEY_DOC_COLUMN);
		Md5PasswordEncoder md5Encoder = new Md5PasswordEncoder();
		
		for (int i = 0; i < header.length; i++) {
			Column col = new Column();
			col.setLabel(header[i]);
			String property = md5Encoder.encodePassword(header[i], null);
			col.setProperty(property.substring(0, 8));
			if(grid.getColumns() == null){
				grid.setColumns(new ArrayList<Column>());
			}
			grid.getColumns().add(col);
		}
		
		return grid;
	}
	
	
	@RequestMapping("/mydoc/config")
	@ResponseBody
	public Grid gridViewConfig(HttpServletRequest request, 
			@RequestParam(REQ_PARAM_GRIDID) String gridId,
			@RequestParam Short docid) throws SystemException, BusinessException {
		ViewConfig config = XmlViewManager.getXmlViewConfig
				(ProjectConst.CATALOG_EIMS, ProjectConst.MODULE_MYDOC);
		return this.gridViewConfig(request, gridId, docid, config);
	}
	
	@RequestMapping("/mydoc/data")
	@ResponseBody
	public MoDocList listMyDocData(HttpServletRequest request, 
			@RequestParam(REQ_PARAM_GRIDID) String gridId,
			@RequestParam Short docid) throws SystemException, BusinessException {
		
		
		UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext()
				.getAuthentication()
				.getPrincipal();
		
		return this.listGridData(request, gridId, docid, userDetails.getUsername());
		
	}
	
}
